package dao

import (
	"fmt"

	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/global"
	jobstatus "openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/common/enum/job"
	"openeuler.org/PilotGo/PilotGo-plugin-automation/internal/module/job_history/model"
)

/***********子作业结果**************/
func SaveSubJobResult(subjobResults []*model.SubJobResult) error {
	if len(subjobResults) == 0 {
		return fmt.Errorf("初始存储数据结果为空")
	}
	return global.App.MySQL.Save(&subjobResults).Error
}

func GetSubJobResult(jobId, ip string) (model.SubJobResult, error) {
	var result model.SubJobResult
	if err := global.App.MySQL.Model(&model.SubJobResult{}).Where("job_id = ? AND ip = ?", jobId, ip).First(&result).Error; err != nil {
		return model.SubJobResult{}, err
	}
	return result, nil
}

func GetSubJobResults(jobId string) ([]model.SubJobResult, error) {
	var subJobResults []model.SubJobResult
	result := global.App.MySQL.Model(&model.SubJobResult{}).Where("job_id = ?", jobId).Find(&subJobResults)
	if result.Error != nil {
		return nil, result.Error
	}
	return subJobResults, nil
}

func UpdateSubJobResult(jobId string, ip string, updates map[string]interface{}) error {
	if jobId == "" || ip == "" {
		return fmt.Errorf("jobId 或 ip 不能为空")
	}

	if len(updates) == 0 {
		return fmt.Errorf("更新内容不能为空")
	}

	if err := global.App.MySQL.Model(&model.SubJobResult{}).
		Where("job_id = ? AND ip = ?", jobId, ip).
		Updates(updates).Error; err != nil {
		return err
	}
	return nil
}

/***********************子作业步骤结果*************************/
func SaveSubJobStepResult(subjobStepResults []*model.SubJobStepResult) error {
	if len(subjobStepResults) == 0 {
		return fmt.Errorf("初始存储数据结果为空")
	}
	return global.App.MySQL.Save(&subjobStepResults).Error
}

func GetSubJobStepResults(jobId, ip string) ([]model.SubJobStepResult, error) {
	var results []model.SubJobStepResult
	if err := global.App.MySQL.Model(&model.SubJobStepResult{}).Where("job_id = ? AND ip = ?", jobId, ip).Order("step_num").Find(&results).Error; err != nil {
		return []model.SubJobStepResult{}, err
	}
	return results, nil
}

func GetSubJobStepResult(jobId, ip string, stepNum int) (model.SubJobStepResult, []model.SubJobStepResult, error) {
	var currentStepResult model.SubJobStepResult
	if err := global.App.MySQL.Model(&model.SubJobStepResult{}).Where("job_id = ? AND ip = ? AND step_num = ?", jobId, ip, stepNum).Find(&currentStepResult).Error; err != nil {
		return model.SubJobStepResult{}, []model.SubJobStepResult{}, err
	}

	var stepResults []model.SubJobStepResult
	if err := global.App.MySQL.Model(&model.SubJobStepResult{}).Where("job_id = ? AND ip = ? AND step_num <= ?", jobId, ip, stepNum).Find(&stepResults).Error; err != nil {
		return currentStepResult, []model.SubJobStepResult{}, err
	}
	return currentStepResult, stepResults, nil
}

func UpdateSubJobStepResult(jobId string, ip string, stepNum int, updates map[string]interface{}) error {
	if jobId == "" || ip == "" {
		return fmt.Errorf("jobId 或 ip 不能为空")
	}

	if len(updates) == 0 {
		return fmt.Errorf("更新内容不能为空")
	}

	if err := global.App.MySQL.Model(&model.SubJobStepResult{}).
		Where("job_id = ? AND ip = ? AND step_num = ?", jobId, ip, stepNum).
		Updates(updates).Error; err != nil {
		return err
	}

	return nil
}

func CheckSubJobsStatus(jobId string) (string, int64, int64, string, error) {
	var subJobs []model.SubJobResult
	if err := global.App.MySQL.Where("job_id = ?", jobId).Find(&subJobs).Error; err != nil {
		return "", 0, 0, "", fmt.Errorf("获取子作业失败: %v", err)
	}
	if len(subJobs) == 0 {
		return "", 0, 0, "", fmt.Errorf("未找到 job_id=%s 的子作业", jobId)
	}

	counts := make(map[string]int)
	var earliestStartTime, latestEndTime int64
	var hasStartTime, hasEndTime bool

	for _, sub := range subJobs {
		counts[sub.ExecCode]++

		// 找最早的开始时间
		if sub.StartTime > 0 {
			if !hasStartTime || sub.StartTime < earliestStartTime {
				earliestStartTime = sub.StartTime
				hasStartTime = true
			}
		}
		// 找最晚的结束时间
		if sub.EndTime > 0 {
			if !hasEndTime || sub.EndTime > latestEndTime {
				latestEndTime = sub.EndTime
				hasEndTime = true
			}
		}
	}

	total := len(subJobs)
	get := func(statusCode string) int { return counts[statusCode] }

	var jobStatusCode string

	switch {
	case get(jobstatus.SubJobProcessingCode) > 0:
		jobStatusCode = jobstatus.JobProcessingCode
	case get(jobstatus.SubJobRunningCode) > 0:
		jobStatusCode = jobstatus.JobRunningCode
	case get(jobstatus.SubJobNotRunCode) == total:
		jobStatusCode = jobstatus.JobNotRunCode
	case get(jobstatus.SubJobSuccessCode) == total:
		jobStatusCode = jobstatus.JobSuccessCode
	case get(jobstatus.SubJobTimeoutCode) == total:
		jobStatusCode = jobstatus.JobDiscontinueCode
	case get(jobstatus.SubJobFailedCode) == total:
		jobStatusCode = jobstatus.JobFailedCode
	case get(jobstatus.SubJobCanceledCode) == total:
		jobStatusCode = jobstatus.JobDiscontinueCode
	// 执行成功 + 其他状态 → 部分成功
	case get(jobstatus.SubJobSuccessCode) > 0:
		jobStatusCode = jobstatus.JobPartSuccessCode
	default:
		jobStatusCode = jobstatus.JobDiscontinueCode
	}

	totalTime := ""
	if hasStartTime && hasEndTime {
		totalTime = calculateTotalTime(earliestStartTime, latestEndTime)
	}

	return jobStatusCode, earliestStartTime, latestEndTime, totalTime, nil
}
